import WeDisplayShaders from './WeDisplayShaders';

const vertexShaderSource = `
precision highp float;
  ${WeDisplayShaders.WeCartesian3FromRadians}
  uniform sampler2D u_particlesTexture0;
  out vec3 v_st;
  out vec3 v_normalEC;
  out vec3 v_positionEC;
  out float v_i;
  vec3 getWorldPosition(vec3 pos) {
    bool useRTCenter = Weget_useRTCenter() > 0.0;
    if(useRTCenter){
      float meterWidth = Weget_meterWidth();
      float meterHeight = Weget_meterHeight();
      vec2 st = pos.xy - 0.5;
      return vec3(st.x * meterWidth,st.y * meterHeight, pos.z);
    }

    vec4 worldExtent = Weget_extent();
    vec2 st = WeGetImageryLonLat(vec2(pos.x,pos.y),worldExtent);
    return we_cartesian3FromRadians(vec3(st,pos.z));
  }

  vec3 lookup_wind(const vec3 particle_pos) {
    bool shouldFlipY = Weget_shouldFlipY() > 0.0;
    vec3 uv = particle_pos;
    if(!shouldFlipY){
      uv.y = 1.0 - uv.y;
    }
    return WeDecodeComponent(uv).xyz;
  }

  void main()
  {
      float meterWidth = Weget_meterWidth();
      float meterHeight = Weget_meterHeight();

      float minValue = Weget_minValue();
      float maxValue = Weget_maxValue();
      float pointSize = Weget_pointSize();
      float particleSize = Weget_particleSize();
      float extrusionAnimeHeight = Weget_extrusionAnimeHeight();
      float offsetZ = Weget_offsetZ();
      float extrusion = Weget_extrusion();
      vec4 worldExtent = Weget_extent();
      float numLon = Weget_numLon();
      float numLat = Weget_numLat();
      float numVertexs = numLon * numLat;
      float position = float(gl_VertexID);
      float face = floor(position / numVertexs);

      float position1 = mod(position,numVertexs);
      float r = floor(position1/numLon) ;
      float c = mod(position1,numLon) ;

      vec2 ws = worldExtent.xy;
      vec2 en = worldExtent.zw;
      float dx = 0.1 / (numLon - 1.0 + 1.0);// 0_1_2, 2 is edge
      float dy = 0.1 / (numLat - 1.0 + 1.0);
      dx = 1.0 / (numLon - 1.0);
      dy = 1.0 / (numLat - 1.0);

      vec2 uv = vec2(c / (numLon - 1.0),r / (numLat - 1.0));
      vec4 particlePos0 = texture(u_particlesTexture0,uv);

      float alpha = (czm_frameNumber - particlePos0.a) / pow(8.0, 2.0);
      float a0 = clamp(alpha,0.5,1.0);

      float height = particleSize * a0;
      offsetZ += extrusionAnimeHeight * a0 * 0.125 + particlePos0.z * extrusion;

      float len = max(dx,dy) * pointSize * a0;

      vec3 dir = lookup_wind(particlePos0.xyz);

      vec4 color = vec4(1.0);

      float speed = length(dir);
      float i = (speed - minValue) / (maxValue - minValue);

      len *= clamp(i,0.25,1.0);
      height *= clamp(i,0.25,1.0);

      dir = normalize(dir);

      vec2 directionRight = vec2(dir.y, -dir.x);
      vec2 xOffset = dir.xy * len;
      vec2 yOffset = directionRight * len * 0.15;

      vec2 lonlat = vec2(particlePos0.x,1.0 - particlePos0.y);
      vec2 lonlat0 = lonlat + yOffset * 0.5;
      vec2 lonlat1 = lonlat + yOffset * 0.5 + xOffset;
      vec2 lonlat2 = lonlat - yOffset * 0.5 + xOffset;
      vec2 lonlat3 = lonlat - yOffset * 0.5;

      float thick = 0.5 * 0.5;

      lonlat0 -= thick * yOffset;
      lonlat3 += thick* yOffset;

      vec3 vertexs[8];
      vertexs[0] = getWorldPosition(vec3(lonlat0,offsetZ + 0.0 + thick * height));
      vertexs[1] = getWorldPosition(vec3(lonlat1,offsetZ + 0.0));
      vertexs[2] = getWorldPosition(vec3(lonlat2,offsetZ + 0.0));
      vertexs[3] = getWorldPosition(vec3(lonlat3,offsetZ + 0.0 + thick * height));
      vertexs[4] = getWorldPosition(vec3(lonlat0,offsetZ + height - thick * height));
      vertexs[5] = getWorldPosition(vec3(lonlat1,offsetZ + height));
      vertexs[6] = getWorldPosition(vec3(lonlat2,offsetZ + height));
      vertexs[7] = getWorldPosition(vec3(lonlat3,offsetZ + height - thick * height));

      vec3 normals[8];
      normals[0] = normalize(cross(vertexs[0] - vertexs[1],vertexs[5] - vertexs[1]));
      normals[1] = normalize(cross(vertexs[1] - vertexs[2],vertexs[6] - vertexs[2]));
      normals[2] = normalize(cross(vertexs[2] - vertexs[3],vertexs[7] - vertexs[3]));
      normals[3] = normalize(cross(vertexs[3] - vertexs[0],vertexs[4] - vertexs[0]));
      normals[4] = normalize(cross(vertexs[6] - vertexs[5],vertexs[4] - vertexs[5]));

      vec3 normal = vec3(0.0,0.0,1.0);
      vec3 st = vec3(0.0);

      vec3 worldCoords;
      float z = 0.0;

      //top
      if(face == 0.0) {
        worldCoords = vertexs[4];
        normal = normals[4];
        st.z = 1.0;
      }
      else if(face == 1.0) {
        worldCoords = vertexs[5];
        normal = normals[4];
        st.x = 1.0;
        st.z = 1.0;
      }
      else if(face == 2.0) {
        worldCoords = vertexs[6];
        normal = normals[4];
        st.x = 1.0;
        st.y = 1.0;
        st.z = 1.0;
      }
      else if(face == 3.0) {
        worldCoords = vertexs[7];
        normal = normals[4];
        st.y = 1.0;
        st.z = 1.0;
      }

       // front
      else if(face == 4.0) {
        worldCoords = vertexs[0];
        normal = normals[0];
      }
      else if(face == 5.0) {
        worldCoords = vertexs[1];
        normal = normals[0];
        st.x = 1.0;
      }
      else if(face == 6.0) {
        worldCoords = vertexs[5];
        normal = normals[0];
        st.x = 1.0;
        st.y = 1.0;
        st.z = 1.0;
      }
      else if(face == 7.0) {
        worldCoords = vertexs[4];
        normal = normals[0];
        st.y = 1.0;
        st.z = 1.0;
      }

       //right
      else if(face == 8.0) {
        worldCoords = vertexs[1];
        normal = normals[1];
      }
      else if(face == 9.0) {
        worldCoords = vertexs[2];
        normal = normals[1];
        st.x = 1.0;
      }
      else if(face == 10.0) {
        worldCoords = vertexs[6];
        normal = normals[1];
        st.x = 1.0;
        st.y = 1.0;
        st.z = 1.0;
      }
      else if(face == 11.0) {
        worldCoords = vertexs[5];
        normal = normals[1];
        st.y = 1.0;
        st.z = 1.0;
      }

      //left
      else if(face == 12.0) {
        worldCoords = vertexs[3];
        normal = normals[2];
      }
      else if(face == 13.0) {
        worldCoords = vertexs[0];
        normal = normals[2];
        st.x = 1.0;
      }
      else if(face == 14.0) {
        worldCoords = vertexs[4];
        normal = normals[2];
        st.x = 1.0;
        st.y = 1.0;
        st.z = 1.0;
      }
      else if(face == 15.0) {
        worldCoords = vertexs[7];
        normal = normals[2];
        st.y = 1.0;
        st.z = 1.0;
      }

      //back
      else if(face == 16.0) {
        worldCoords = vertexs[2];
        normal = normals[3];
      }
      else if(face == 17.0) {
        worldCoords = vertexs[3];
        normal = normals[3];
        st.x = 1.0;
      }
      else if(face == 18.0) {
        worldCoords = vertexs[7];
        normal = normals[3];
        st.x = 1.0;
        st.y = 1.0;
        st.z = 1.0;
      }
      else if(face == 19.0) {
        worldCoords = vertexs[6];
        normal = normals[3];
        st.y = 1.0;
        st.z = 1.0;
      }

      v_st = st;
      v_i = i;
      v_normalEC = czm_normal * normal;
      v_positionEC = (czm_modelView * vec4(normal,1.0)).xyz;
      gl_Position = czm_modelViewProjection * vec4(worldCoords,1.0);
      // gl_Position *= visible;
  }
`

const fragmentShaderSource = `
  ${WeDisplayShaders.WePhong}
  in vec3 v_st;
  in vec3 v_normalEC;
  in vec3 v_positionEC;
  in float v_i;
  void main()
  {
      bool colorize = Weget_colorize() > 0.0;
      vec4 color = vec4(1.0);
      if(colorize){
          color = texture(u_TFTexture,vec2(v_i,0.0));
      }
      color.rgba *= ((v_st.x + 0.75) / 1.75);
      vec3 normalEC = v_normalEC;
      vec3 positionEC = -v_positionEC;

      czm_materialInput materialInput;
      materialInput.normalEC = normalEC;
      materialInput.positionToEyeEC = -v_positionEC;
      czm_material material = czm_getDefaultMaterial(materialInput);
      material.diffuse = color.rgb;
      material.alpha = color.a;
      out_FragColor = czm_phong(normalize(-v_positionEC.xyz), material, czm_lightDirectionEC);

      // color.rgb = WePhong(color.rgb,0.1,normalize(positionEC), czm_sunDirectionEC,normalize(normalEC));
      // out_FragColor = color;
  }
`

export default { vertexShaderSource, fragmentShaderSource }
